<?php

namespace business\elasticsearch\services;

use business\elasticsearch\models\BigDataSaasSupplierModel;

class BigDataSaasSupplierService
{
    public function getDataList(
        $keyword = [],
        $province = [],
        $city = '',
        $area = [],
        $projectArea = [],
        $projectStartTime = '',
        $projectEndTime = '',
        $industryCategoryMiddle = [],
        $createdTime = '',
        $page = 1,
        $pageSize = 20
    )
    {

        $condition = $this->constructCondition(
            $keyword,
            $province,
            $city,
            $area,
            $projectArea,
            $projectStartTime,
            $projectEndTime,
            $industryCategoryMiddle,
            $createdTime
        );
//        echo json_encode($condition);exit;
        $query = BigDataSaasSupplierModel::find()->query($condition);

        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "supplier_name" => new \stdClass(),
                "projects.company" => new \stdClass(),
                "projects.project_name" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['is_new' => SORT_DESC, "_score" => SORT_DESC]);

        $total = $query->count();
        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $data = $query->asArray()->all();
        \yii::info("saas-supplier-result", json_encode($data, JSON_UNESCAPED_UNICODE));
        //数据处理
        $result = ['total' => $total, 'list' => []];
        foreach ($data as $dv) {
            $tmp = $dv['_source'];
            $tmp['nameSuggest'] = $tmp['supplier_name'];
            $tmp['projectSuggest'] = [];
            if (!empty($dv['highlight'])) {
                foreach ($dv['highlight'] as $key => $value) {
                    $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';

                    if (in_array($key, ["projects.company", "projects.project_name"])) {
                        $valueArray = array_unique($value);
                        foreach ($valueArray as $v) {
                            foreach ($tmp["projects"] as $i => $project) {
                                $originalValue = str_replace("<em class=\"_high\">", "", str_replace("</em>", "", $v));
                                $project['province_code'] = $project['province_code'] ?? "";
                                $project['city_code'] = $project['city_code'] ?? "";
                                if ($project[substr($key, 9)] == $originalValue
                                    && (empty($projectArea) || in_array($project['province_code'], $projectArea) || in_array($project['city_code'], $projectArea))
                                    && (empty($projectStartTime) || $project["date"] >= $projectStartTime)
                                    && (empty($projectEndTime) || $project["date"] <= $projectEndTime)
                                ) {
                                    $project[substr($key, 9) . 'HL'] = $v;
                                    $tmp['projectSuggest'][] = $project;
                                }
                                //if(preg_match("/\<em class=\"_high\"\>.*\<\/em\>/", $tmp[$key . 'HL'])
                            }
                        }
                    }
                }
            }

            $tmp = $this->formatSaasSupplier($tmp);
            $result['list'][] = $tmp;
        }
        \yii::info("saas-supplier-result2", json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    private function constructCondition(
        $keyword = [],
        $province = [],
        $city = '',
        $area = [],
        $projectArea = [],
        $projectStartTime = '',
        $projectEndTime = '',
        $industryCategoryMiddle = [],
        $createdTime = ''
    )
    {
        // 行业分分类 and 更新时间 and 供应商地区 and ( (公司名称匹配关键词 and 公司地址匹配省市 and 近一年有项目) or (近一年有项目 and 项目标题或合作单位匹配关键字 and 项目地址匹配省市) )
        // {
        //  "query": {
        //    "bool": {
        //      "must": [
        //        {
        //          行业分分类、更新时间等条件
        //        },
        //        {
        //          "bool": {
        //            "should": [
        //              {
        //                "bool": {
        //                  "must": [
        //                    {公司名称匹配关键词},{公司地址匹配省市},{近一年有项目}
        //                  ]
        //                }
        //              },{
        //                "bool": {
        //                  "must": [
        //                    {近一年有项目},{项目标题或合作单位匹配关键字},{项目地址匹配省市}
        //                  ]
        //                }
        //              }
        //            ]
        //          }
        //         }
        //      ]
        //    }
        //  }
        //}
        $query = [];
        $slop = !empty(\Yii::$app->params['CommonDataDeveloperSlop']) ? \Yii::$app->params['CommonDataDeveloperSlop'] : 2;
        $must = [];
        $query['function_score']['query']['bool']['must'] = &$must;

        // 1.行业分分类
        if (!empty($industryCategoryMiddle)) {
            $must[] = ["terms" => ['industry_category_middle' => $industryCategoryMiddle]];
        }

        // 2.更新时间
        if (!empty($createdTime)) {
            $dateRange = [];
            $dateRange['from'] = $createdTime;
            $dateRange['to'] = date('Y-m-d H:i:s', time());
            $must[] = ['range' => ['modified_on' => $dateRange]];
        }

        // 3.供应商的地区，兼容省市混排的情况
        if (!empty($area)) {
            $shouldArea = [];
            $must[] = ['bool' => ['should' => &$shouldArea]];
            $shouldArea[] = ["terms" => ['province_code' => $area]];
            $shouldArea[] = ["terms" => ['city_code' => $area]];
        } else {
            // 供应商的省市精确查询
            if (!empty($province)) {
                $must[] = ["terms" => ['province_code' => $province]];
            }
            if (!empty($city)) {
                $must[] = ["term" => ['city_code' => $city]];
            }
        }

        // 4.1 (公司名称匹配关键词 and 公司地址匹配省市 and 近一年有项目)
        $companyCondition = [];
        if (!empty($keyword)) {
            $companyKeywordCondition = [];  //公司名称匹配关键词
            foreach ($keyword as $k) {
                $companyKeywordCondition[] = [
                    'match_phrase' => ['supplier_name' => ["query" => $k, "boost" => 100, 'slop' => $slop]]
                ];
            }
//            $companyCondition["bool"]["must"][] = $companyKeywordCondition;
            $companyCondition["bool"]["must"][] = ["bool" => ["should" => $companyKeywordCondition]];
        }

        // 4.2 (近一年有项目 and 项目标题或合作单位匹配关键字 and 项目地址匹配省市)
//        $projectCondition = ["nested" => [
//            "path" => "projects",
//            "query" => [
//                "bool" => [
//                    "must" => []
//                ]
//            ]
//        ]];
        $projectCondition = [];


        //项目标题或合作单位匹配关键字
        if (!empty($keyword)) {
            $projectKeywordCondition = [];
            foreach ($keyword as $k) {
                $projectKeywordCondition[] = [
                    'match_phrase' => ['projects.project_name' => ["query" => $k, "boost" => 10, 'slop' => $slop]]
                ];
                $projectKeywordCondition[] = [
                    'match_phrase' => ['projects.company' => ["query" => $k, "boost" => 1, 'slop' => $slop]]
                ];
            }
            $projectCondition["nested"]["query"]["bool"]["must"][] = ["bool" => ["should" => $projectKeywordCondition]];
            $projectCondition["nested"]["path"] = "projects";
        }

        // 项目地址匹配省市
        if (!empty($projectArea)) {
            $projectAreaCondition = [
                "bool" => [
                    "should" => [
                        [
                            "terms" => [
                                "projects.province_code" => $projectArea
                            ]
                        ], [
                            "terms" => [
                                "projects.city_code" => $projectArea
                            ]
                        ]
                    ]
                ]
            ];
            $projectCondition["nested"]["path"] = "projects";
            $projectCondition["nested"]["query"]["bool"]["must"][] = $projectAreaCondition;
        }

        $comboCondition = [];
//        echo "projectCondition:" . json_encode($projectCondition);
        if (!empty($projectCondition)) {
            if (!empty($projectStartTime) && !empty($projectEndTime)) {
                $timeCondition = [
                    "range" => [
                        "projects.date" => [
                            "from" => $projectStartTime,
                            "to" => $projectEndTime
                        ]
                    ]
                ];
                $projectCondition["nested"]["query"]["bool"]["must"][] = $timeCondition;
            }
            $comboCondition[] = $projectCondition;
        }
        if (!empty($companyCondition)) {
            //时间区间内有项目
            if (!empty($projectStartTime) && !empty($projectEndTime)) {
                $companyProjectCondition = [
                    "nested" => [
                        "path" => "projects",
                        "query" => [
                            "range" => [
                                "projects.date" => [
                                    "from" => $projectStartTime,
                                    "to" => $projectEndTime
                                ]
                            ]
                        ]
                    ]
                ];
                $companyCondition["bool"]["must"][] = $companyProjectCondition;
            }
            $comboCondition[] = $companyCondition;
        }
        if (!empty($comboCondition)) {
            $must[] = [
                "bool" => [
                    "should" => $comboCondition
                ]
            ];
        } else {
            //时间区间内有项目
            if (!empty($projectStartTime) && !empty($projectEndTime)) {
                $must[] = [
                    "nested" => [
                        "path" => "projects",
                        "query" => [
                            "range" => [
                                "projects.date" => [
                                    "from" => $projectStartTime,
                                    "to" => $projectEndTime
                                ]
                            ]
                        ]
                    ]
                ];
            }
        }


//        echo json_encode($query);
//        exit;
        return $query;
    }


    public function guessNames($keyword, $pageSize)
    {
        $page = 1;

        $query = [];
        if (!empty($keyword)) {
            $query['function_score']['query']['bool']['must'][] = [
                'match_phrase' => ['supplier_name' => $keyword]
            ];
        }

        $query = BigDataSaasSupplierModel::find()
            ->query($query);

        //高亮处理
        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "supplier_name" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['_score' => SORT_DESC]);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $data = $query->asArray()->all();
        //数据处理
        $result = [];
        foreach ($data as $dv) {
            $item = array();
            $tmp = $dv['_source'];
            $tmp['nameSuggest'] = $tmp['supplier_name'];
            if (!empty($dv['highlight'])) {
                foreach ($dv['highlight'] as $key => $value) {
                    $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';
                }
            }
            $item['title'] = $tmp['supplier_name'];
            $item['titleHL'] = $tmp['supplier_nameHL'];
            $result[] = $item;
        }
        return $result;
    }


    public function formatSaasSupplier($data)
    {
        //1、显示赋值：因为 es 的值如果为 null 会没有字段
        $return_params = [
            'pulsar_time' => 'string',
            'id' => 'string',
            'supplier_id' => 'string',
            'supplier_name' => 'string',
            'supplier_logo' => 'string',
            'legal_name' => 'string',
            'organizing_code' => 'string',
            'regist_capi' => 'string',
            'establish_date' => 'string',
            'term_start' => 'string',
            'term_end' => 'string',
            'status' => 'string',
            'enterprise_nature' => 'string',
            'scope' => 'string',
            'category' => 'string',
            'province' => 'string',
            'province_code' => 'string',
            'city' => 'string',
            'city_code' => 'string',
            'address' => 'string',
            'number_of_employees' => 'string',
            'company_profile' => 'string',
            'coop_cnt' => 'int',
            'contact_cnt' => 'string',
            'coop_amt' => 'string',
            'coop_amt_1year' => 'string',
            'coop_cnt_1year' => 'string',
            'contact_cnt_1year' => 'string',
            'modified_on' => 'string',
            'score_tel' => 'int',
            'industry_category' => 'string',
            'industry_category_big' => 'string',
            'industry_category_middle' => 'string',
            'industry_category_small' => 'string',
            'is_new' => 'int',
            'name_traditional' => 'string',
        ];

        foreach ($return_params as $rk => $rv) {
            $tmp = isset($data[$rk]) ? $data[$rk] : '';
            $tmp = $tmp === '1990-01-01 00:00:00' ? '' : $tmp;
            if ($rv == 'int') {
                $data[$rk] = (int)$tmp;
            } elseif ($rv == 'array') {
                $data[$rk] = empty($tmp) ? [] : $tmp;
            } else {
                $data[$rk] = $tmp;
            }

        }

        return $data;
    }
}